﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace BurnSystems.Gpx
{
    /// <summary>
    /// This class stores some extension methods for setting and getting information
    /// into xmlnodes
    /// </summary>
    public static class GpxExtensionMethods
    {
        /// <summary>
        /// Gets the element content of an subelement of an element by its nodename
        /// </summary>
        /// <param name="element">Element, from which the information shall be retrieved</param>
        /// <param name="elementName">Name of the element</param>
        /// <param name="defaultValue">Stores the default value</param>
        /// <returns>Content of the element or default value</returns>
        public static string GetElementContent(this XElement element, string elementName, string defaultValue)
        {
            elementName = GpxDocument.FullyQualifiedNS + elementName;

            var node = element.Element(elementName);
            if (node == null)
            {
                return defaultValue;
            }

            return node.Value;
        }

        /// <summary>
        /// Gets the element content of an subelement of an element by its nodename
        /// </summary>
        /// <param name="element">Element, from which the information shall be retrieved</param>
        /// <param name="elementName">Name of the element</param>
        /// <param name="defaultValue">Stores the default value</param>
        /// <returns>Content of the element or default value</returns>
        public static string GetAttributeContent(this XElement element, string elementName, string defaultValue)
        {
            var node = element.Attribute(elementName);
            if (node == null)
            {
                return defaultValue;
            }

            return node.Value;
        }

        /// <summary>
        /// Gets the element content of an subelement of an element by its nodename
        /// </summary>
        /// <param name="element">Element, from which the information shall be retrieved</param>
        /// <param name="elementName">Name of the element</param>
        /// <param name="content">Content to be set</param>
        public static void SetElementContent(this XElement element, string elementName, string content)
        {
            elementName = GpxDocument.FullyQualifiedNS + elementName;

            var node = element.Element(elementName);
            if (node == null)
            {
                node = new XElement(elementName);
                node.Value = content;
                element.Add(node);
                return;
            }

            node.Value = content;
        }

        /// <summary>
        /// Gets the element content of an subelement of an element by its nodename
        /// </summary>
        /// <param name="element">Element, from which the information shall be retrieved</param>
        /// <param name="elementName">Name of the element</param>
        /// <param name="content">Content to be set</param>
        public static void SetAttributeContent(this XElement element, string elementName, string content)
        {
            elementName = GpxDocument.FullyQualifiedNS + elementName;

            var node = element.Attribute(elementName);
            if (node == null)
            {
                node = new XAttribute(elementName, content);
                element.Add(node);
                return;
            }

            node.Value = content;
        }

        /// <summary>
        /// Gets the biggest boundingbox for an enumeration of bounding boxes
        /// </summary>
        /// <param name="boundingBoxes">List of bounding boxes</param>
        /// <returns>The boundingbox containing all bounding boxes</returns>
        public static BoundingBox Max( IEnumerable<BoundingBox> boundingBoxes )
        {
            var result = new BoundingBox();
            var first = true;

            foreach (var boundingBox in boundingBoxes)
            {
                if (first)
                {
                    first = false;
                    result.Left = boundingBox.Left;
                    result.Right = boundingBox.Right;
                    result.Top = boundingBox.Top;
                    result.Bottom = boundingBox.Bottom;
                }
                else
                {
                    result.Add(boundingBox);
                }
            }

            // No bounding box found
            if (first)
            {
                return null;
            }

            // Return result
            return result;
        }
    }
}
